
//
// Copyright (c) 2008, the /*jupiter jazz*/ group
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the /*jupiter jazz*/ group nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY the /*jupiter jazz*/ group ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL the /*jupiter jazz*/ group BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

// Interface header.
#include "tile.h"

namespace foundation
{

//
// Tile class implementation.
//

// Construct a new tile. The content of the tile is left undefined.
Tile::Tile(
    const PixelFormat   pixel_format,           // pixel format
    const size_t        width,                  // tile width, in pixels
    const size_t        height,                 // tile height, in pixels
    const size_t        channel_count,          // number of channels
    unsigned char*      storage)                // if provided, use this memory for pixel storage
  : m_pixel_format(pixel_format)
  , m_width(width)
  , m_height(height)
  , m_channel_count(channel_count)
  , m_pixel_count(width * height)
{
    // Sanity checks.
    assert(m_width > 0);
    assert(m_height > 0);
    assert(m_channel_count > 0);
    assert(m_pixel_count > 0);

    // Compute the size in bytes of one channel.
    m_channel_size = pixel_size(m_pixel_format);

    // Compute the size in bytes of one pixel.
    m_pixel_size = m_channel_size * m_channel_count;

    // Compute the size in bytes of the pixel array.
    m_array_size = m_pixel_size * m_pixel_count;

    // Allocate the pixel array.
    if (storage)
    {
         m_pixel_array = storage;
         m_own_storage = false;
    }
    else
    {
        m_pixel_array = new unsigned char[m_array_size];
        m_own_storage = true;
    }
}

// Copy constructor.
Tile::Tile(const Tile&  rhs)
  : m_pixel_format(rhs.m_pixel_format)
  , m_width(rhs.m_width)
  , m_height(rhs.m_height)
  , m_channel_count(rhs.m_channel_count)
  , m_pixel_count(rhs.m_pixel_count)
  , m_channel_size(rhs.m_channel_size)
  , m_pixel_size(rhs.m_pixel_size)
  , m_array_size(rhs.m_array_size)
{
    // Allocate pixel array.
    m_pixel_array = new unsigned char[m_array_size];
    m_own_storage = true;

    // Copy pixels from source tile.
    std::memcpy(m_pixel_array, rhs.m_pixel_array, m_array_size);
}

// Destructor.
Tile::~Tile()
{
    // Deallocate pixel array.
    if (m_own_storage)
        delete [] m_pixel_array;
}

}   // namespace foundation
